﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Common;
using Models;
using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
using Senparc.Weixin.MP.Containers;
using Senparc.Weixin.MP.Helpers;
using Senparc.Weixin.MP.TenPayLib;
using Senparc.Weixin.MP.TenPayLibV3;

namespace Web.Controllers.View
{
    public class PayController : Controller
    {

        #region 1、获取用户基本信息
        /// <summary>
        /// 获取用户基本信息
        /// </summary>
        /// <param name="code">微信回调参数</param>
        /// <returns></returns>
        public ActionResult Index(string code)
        {
            // 获取当前页面地址作为回调地址
            var redirectUrl = WebHelper.GetUrl();

            #region 微信授权登录
            if (string.IsNullOrEmpty(code))
            {
                var wechatAuthorizeUrl = OAuthApi.GetAuthorizeUrl(WxConfig.APPID, redirectUrl
                    , "STATE", OAuthScope.snsapi_userinfo);
                return Redirect(wechatAuthorizeUrl);
            }

            var accesstokenresult = OAuthApi.GetAccessToken(WxConfig.APPID, WxConfig.APPSECRET, code);
            var oauthuserinfo = OAuthApi.GetUserInfo(accesstokenresult.access_token, accesstokenresult.openid);

            Session["USER_INFO"] = oauthuserinfo;
            return Redirect("/pay/paying");
            #endregion
        }
        #endregion

        #region 2、订单详情，调起JS支付
        /// <summary>
        /// 订单详情，调起JS支付
        /// </summary>
        /// <returns></returns>
        public ActionResult Paying()
        {
            if (Session["USER_INFO"] == null) return Redirect("/pay");
            
            // 获取业务订单基本信息，此处默认支付金额为0.01元
            var money = "0.01";
            var oauthuserinfo = (OAuthUserInfo) Session["USER_INFO"];
            var outTradeNo = WxHelper.GenerateOutTradeNo();   // 生成商户订单编号
            var totalFee = (int)(Convert.ToDouble(money) * 100);    // 支付金额转为“分”的整数

            #region 生成统一下单所需参数
            TenPayV3UnifiedorderRequestData tenPayV3UnifiedorderRequestData
                = new TenPayV3UnifiedorderRequestData(
                    WxConfig.APPID,
                    WxConfig.MCHID,
                    oauthuserinfo.nickname,
                    outTradeNo,
                    totalFee,
                    WebHelper.GetIP(),
                    "http://hnabc.cn/pay/result",
                    TenPayV3Type.JSAPI,
                    oauthuserinfo.openid,
                    WxConfig.KEY,
                    TenPayUtil.GetNoncestr());
            #endregion

            #region 调用统一下单接口
            UnifiedorderResult unifiedorderResult = TenPayV3.Unifiedorder(tenPayV3UnifiedorderRequestData);
            if (unifiedorderResult.return_code == "SUCCESS" && unifiedorderResult.result_code == "SUCCESS")
            {
                ViewBag.UnifiedorderResult = unifiedorderResult;
                var APPID = WxConfig.APPID;
                var timestamp = JSSDKHelper.GetTimestamp();
                var nonceStr = JSSDKHelper.GetNoncestr();
                var package = "prepay_id=" + unifiedorderResult.prepay_id;
                var signType = "MD5";

                ViewBag.APPID = APPID;
                ViewBag.timestamp = timestamp;
                ViewBag.nonceStr = nonceStr;
                ViewBag.package = package;
                ViewBag.signType = signType;
                ViewBag.paySign = TenPayV3.GetJsPaySign(APPID, timestamp, nonceStr, package, WxConfig.KEY, signType);
            }
            else
            {
                // 统一下单失败
                return Content(unifiedorderResult.return_msg);
            }
            #endregion

            return View(tenPayV3UnifiedorderRequestData);
        }
        #endregion

        #region 3、微信支付结果回调
        /// <summary>
        /// 微信支付结果回调
        /// </summary>
        /// <returns></returns>
        public ActionResult Result()
        {
            // 获取页面提交的参数
            var resHandler = new Senparc.Weixin.MP.TenPayLibV3.ResponseHandler(System.Web.HttpContext.Current);

            //返回给微信的请求
            var reqHandler = new Senparc.Weixin.MP.TenPayLibV3.RequestHandler(null);

            OrderQueryResult orderQueryResult = new OrderQueryResult(resHandler.ParseXML());
            if (orderQueryResult.return_code != "SUCCESS" || orderQueryResult.result_code != "SUCCESS")
            {
                reqHandler.SetParameter("return_code", "SUCCESS");
                reqHandler.SetParameter("return_msg", "微信支付失败");
                return Content(reqHandler.ParseXML());
            }

            // 业务订单状态查询及处理
            //（1）判断订单是否存在
            //（2）判断订单是否支付
            //（3）订单存在、且为未支付时，更新订单状态

            #region 发送支付成功消息给用户
            var accesstoken = AccessTokenContainer.GetAccessToken(WxConfig.APPID);
            var openId = orderQueryResult.openid;
            var templateId = "2mqEITbuPNf5M6EvQ_fG7HytG4rs9JRHZENTztl2cvE";
            var linkUrl = "";    //点击详情后跳转后的链接地址，为空则不跳转  

            //为模版中的各属性赋值  
            var templateData = new PaySuccess()
            {
                first = new TemplateDataItem(string.Format("支付成功！订单编号：{0}",orderQueryResult.out_trade_no), "#CC0033"),
                orderProductPrice = new TemplateDataItem(orderQueryResult.total_fee, "#99CC00"),
                orderProductName = new TemplateDataItem(orderQueryResult.detail, "#99CC00"),
                orderAddress = new TemplateDataItem("-", "#99CC00"),
                orderName = new TemplateDataItem("-", "#99CC00"),
                remark = new TemplateDataItem("如需帮助，请在公众号留言！", "#CC0033")
            };

            var sendResult =
                   TemplateApi.SendTemplateMessage(accesstoken, openId, templateId, linkUrl, templateData);
            if (sendResult.errcode != ReturnCode.请求成功)
            {
                reqHandler.SetParameter("return_code", "SUCCESS");
                reqHandler.SetParameter("return_msg", "发送支付结果模板消息失败");
                return Content(reqHandler.ParseXML());
            }
            #endregion

            reqHandler.SetParameter("return_code", "SUCCESS");
            reqHandler.SetParameter("return_msg", "订单的支付状态更新成功");
            return Content(reqHandler.ParseXML());
        }
        #endregion

    }
}
